package cn.ejiakanghu.logistics.third.shunfeng;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.codec.digest.DigestUtils;
import org.linlinjava.litemall.core.util.HttpUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.db.domain.AgedmallTags;
import org.linlinjava.litemall.db.util.LogisticsGoodsUtil;
import org.linlinjava.litemall.db.vo.logistics.LogisticsCommonData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 顺丰对接功能工具
 * @author houzb
 * @Description
 * @create 2021-12-01 17:40
 */
public class ThirdLogisticShunFengTool {
    private static final Logger logger = LoggerFactory.getLogger(ThirdLogisticShunFengTool.class);

    //test
//    private static final String appSecrets = "JH9LxbIRh0naEd3VL7I27whYhBEq1EOJ4OQ";
//    private static final String appCode = "YUQIANG";

    //online
    private static final String appSecrets = "JH9LxbIRh0naEd3VL7I27whYhBEq1EOJ4OQ";
    private static final String appCode = "LBBYL";
    //
    /**
     * 下单接口
     */
    private static final String CREATE_ORDER_URL = "https://hda2-ms.sf-express.com/manager/open/order/v2/create";
    /**
     * 订单路由查询
     */
    private static final String GET_ORDER_ROUTE_URL = "https://hda2-ms.sf-express.com/manager/open/order/routeQuery";

    /**
     * 获取签名值
     * @param timestamp
     * @param appSecrets
     * @return
     */
    private static String generateSign(Map<String, Object> params, String timestamp, String appSecrets) {
        StringBuilder sb = new StringBuilder();
        if (params != null && params.size() > 0) {
            List<String> keys = new ArrayList<>(params.keySet());
            Collections.sort(keys);
            for (String key : keys) {
                Object value = params.get(key);
                if (value != null) {
                    sb.append(key).append("=").append(value).append("&");
                }
            }
        }
        sb.append(timestamp).append("&").append(appSecrets);
        return DigestUtils.md5Hex(sb.toString());
    }

    /**
     * 参数名 	   必选  类型 	长度 	说明
     * isGenBillNo 	否 	string 	10 	是否生成运单号 2：不生成运单号，其他：生成运单号
     * mailno 	条件 	string 	20 	运单号 是否生成运单号为2时，必填
     * masterMailno 	条件 	string 	50 	母单号 是否生成运单号为2时，必填
     * mainMailno 	否 	string 	1024 	批次号
     * boxNo 	是 	string 	50 	客户订单号（箱号），可以多个拼接
     * dispatchNo 	是 	string 	20 	派单号 如没有，则填“客户订单号”
     * storeId 	是 	string 	20 	门店ID，如果没有门店ID，则填写组织编码
     * storeName 	否 	string 	20 	门店名称
     * custCode 	否 	string 	20 	商户ID
     * custName 	否 	string 	20 	商户名称
     * count 	是 	string 	10 	件数
     * goodsCount 	否 	string 	10 	物品件数 每件包含的物品数量
     * weight 	否 	string 	20 	重量
     * dcontact 	是 	string 	20 	收件人
     * dtel 	是 	string 	20 	收件电话
     * daddress 	是 	string 	256 	收件地址 省+市+区+具体地址
     * dcompany 	否 	string 	50 	收件公司
     * jcontact 	是 	string 	20 	寄件人
     * jtel 	是 	string 	20 	寄件电话
     * jaddress 	是 	string 	256 	寄件地址 省+市+区+具体地址
     * jcompany 	否 	string 	50 	寄件公司
     * cargo 	是 	string 	50 	拖寄物
     * payMethod 	是 	string 	10 	付款方式 1：寄方付 2：收方付 3:第三方付
     * custId 	否 	string 	20 	月结账号
     * expressType 	是 	string 	5 	产品类型 1：顺丰特快 2：顺丰标快等
     * isCod 	否 	string 	5 	是否代收货款 1：代收货款，其他：不是代收货款
     * collectingMoney 	条件 	double 	（10,2） 	代收货款金额 是否代收货款为1时，必填
     * collectingCardNumber 	条件 	string 	20 	代收卡号 是否代收货款为1时，必填
     * isReturnTracking 	否 	string 	5 	是否生成签回单 1：生成签回单号，其他：不生成签回单号
     * custPayTime 	是 	string 	50 	客户支付时间 格式为：2019-04-21 14:42:27 如无支付时间，则当前时间
     * orderRemark 	否 	string 	256 	备注
     * isMerge 	否 	string 	5 	是否合并订单 1：合并，其他：不合并
     * destCode 	否 	string 	50 	目的地代码
     * addedServiceName 	否 	string 	50 	增值服务名称
     * addedServiceValue 	否 	string 	50 	增值服务扩展属性
     * addedServiceValue1 	否 	string 	50 	增值服务扩展属性1
     * organizationCode 	否 	string 	50 	组织编码
     * isDocall 	否 	string 	5 	是否下call 1：下call，其他：不下call
     * twoDimensionCode 	否 	string 	256 	二维码 如： MMM={‘k1’:’023W’,’k2’:’023DB’,’k3’:’’,’k4’:’T4’,’k5’:’444143702966’,’k6’:’’,’k7’:’5ede720f’}
     *
     */
    private static Map<String, Object> getCreateOrderBody(ShunfengCreateOrderBody orderBody) {
        Map<String, Object> body = new TreeMap<>();
        body.put("mainMailno", orderBody.getMainMailno());
        body.put("boxNo", orderBody.getBoxNo());
        body.put("dispatchNo", orderBody.getDispatchNo());
        body.put("storeId", orderBody.getStoreId());
        body.put("storeName", orderBody.getStoreName());
        body.put("custCode", orderBody.getCustCode());
        body.put("custName", orderBody.getCustName());
        body.put("count", orderBody.getCount());
        body.put("goodsCount", orderBody.getGoodsCount());
        body.put("weight", orderBody.getWeight());
        body.put("dcontact", orderBody.getDcontact());
        body.put("dtel", orderBody.getDtel());
        body.put("daddress", orderBody.getDaddress());
        body.put("jcontact", orderBody.getJcontact());
        body.put("jtel", orderBody.getJtel());
        body.put("jaddress", orderBody.getJaddress());
        body.put("cargo", orderBody.getCargo());
        body.put("payMethod", orderBody.getPayMethod());
        body.put("custId", orderBody.getCustId());
        body.put("expressType", orderBody.getExpressType());
        body.put("isCod", orderBody.getIsCod());
        body.put("collectingMoney", orderBody.getCollectingMoney());
        body.put("collectingCardNumber", orderBody.getCollectingCardNumber());
        body.put("isReturnTracking", orderBody.getIsReturnTracking());
        body.put("custPayTime", orderBody.getCustPayTime());
        body.put("orderRemark", orderBody.getOrderRemark());
        body.put("isMerge", orderBody.getIsMerge());
        body.put("isGenBillNo", orderBody.getIsGenBillNo());
        body.put("mailno", orderBody.getMailno());
        body.put("masterMailno", orderBody.getMasterMailno());
        body.put("destCode", orderBody.getDestCode());
        body.put("addedServiceName", orderBody.getAddedServiceName());
        body.put("addedServiceValue", orderBody.getAddedServiceValue());
        body.put("addedServiceValue1", orderBody.getAddedServiceValue1());
        body.put("organizationCode", orderBody.getOrganizationCode());
        body.put("isDocall", orderBody.getIsDocall());
        return body;
    }


    /**
     * 顺丰下单
     * @param orderBody
     */
    public static ShunfengResponseData<ShunfengResposeCreateOrder> createOrder(ShunfengCreateOrderBody orderBody) {
        Map<String, Object> bodyMap = getCreateOrderBody(orderBody);
        LocalDateTime time = LocalDateTime.now();
        String timestamp = time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //签名
        String sign = generateSign(bodyMap, timestamp, appSecrets);

        //请求头信息
        ReqHead reqHead = new ReqHead();
        reqHead.setSign(sign);
        reqHead.setAppCode(appCode);
        reqHead.setTimestamp(timestamp);

        ShunfengReqData orderData = new ShunfengReqData();
        orderData.setBody(bodyMap);
        orderData.setHead(reqHead);

        //请求下单
        String postData = JSONObject.toJSONString(orderData);
        logger.debug("顺丰下单参数:{},postData={}",orderBody.getBoxNo(), postData);
        String result = HttpUtil.sendPost(CREATE_ORDER_URL, postData, "application/json");
        logger.debug("顺丰下单结果:{},rst={}", orderBody.getBoxNo(), result);

        Type type = new TypeToken<ShunfengResponseData<ShunfengResposeCreateOrder>>(){}.getType();
        ShunfengResponseData<ShunfengResposeCreateOrder> responseData = JacksonUtil.gson.fromJson(result, type);
        return responseData;
    }

    /**
     * 查询物流节点信息
     * @param trackingNumber 运单号,如果有多个单号,以逗号分隔,如”123,124,125”
     * @param checkPhoneNo 校验电话号码后四位值;按运单号查询路由时,可通过该参数传入用于校验的电话号码后4位(寄方或收方都可以),如果涉及多个运单号,对应该值也需按顺序传入多个,并以英文逗号隔开。
     * @return
     */
    public static ShunfengResponseData<ShunfengRespRouteData> getRouteData(String trackingNumber, String checkPhoneNo) {
        Map<String, Object> bodyMap = new TreeMap<>();
        bodyMap.put("checkPhoneNo", checkPhoneNo);
        bodyMap.put("trackingNumber", trackingNumber);
        LocalDateTime time = LocalDateTime.now();
        String timestamp = time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //签名
        String sign = generateSign(bodyMap, timestamp, appSecrets);

        //请求头信息
        ReqHead reqHead = new ReqHead();
        reqHead.setSign(sign);
        reqHead.setAppCode(appCode);
        reqHead.setTimestamp(timestamp);

        ShunfengReqData reqData = new ShunfengReqData();
        reqData.setBody(bodyMap);
        reqData.setHead(reqHead);

        //请求路由路径信息
        String postData = JSONObject.toJSONString(reqData);
        logger.debug("顺丰路由参数:{},{},postData={}",trackingNumber, checkPhoneNo, postData);
        String result = HttpUtil.sendPost(GET_ORDER_ROUTE_URL, postData, "application/json");
        logger.debug("顺丰路由结果:{},{},rst={}", trackingNumber, checkPhoneNo, result);
        Type type = new TypeToken<ShunfengResponseData<ShunfengRespRouteData>>(){}.getType();
        ShunfengResponseData<ShunfengRespRouteData> routeData = JSONObject.parseObject(result, type);
        return routeData;
    }

    public static void main(String[] args) {
        ShunfengCreateOrderBody body = new ShunfengCreateOrderBody();
        String lgContent = "{\"goodsDataList\":[{\"deposit\":true,\"goodsAmount\":2.00,\"goodsCount\":\"1\",\"goodsName\":\"多功能高背轮椅【租赁带配件商品】\",\"orderGoodsId\":36,\"picUrl\":\"https://litemall-admin-001.oss-cn-hangzhou.aliyuncs.com/image/%E4%B8%BB%E5%9B%BE2-1461167005787885568.png?Expires=4790804336&OSSAccessKeyId=LTAI5tKdb79Meq5HqDAupYVB&Signature=%2FeHlVDgZt%2FmuGDg%2BmNGtccKeo5o%3D\",\"spec\":\"HBG \"}],\"orderData\":{\"bigOrderSn\":\"20211207171739000087\",\"payId\":\"4200001319202112072928469372\"},\"storeCloudData\":{\"address\":\"江苏省苏州市苏州工业园区腾飞创意园A1-614\",\"id\":7,\"isThirdPart\":0,\"logisticsName\":\"顺丰\",\"logisticsPhone\":\"95338\",\"name\":\"老宝贝门店\",\"storePhone\":\"18143314474\"},\"timeData\":{},\"userData\":{\"address\":\"江苏省苏州市吴中区启月街菁英公寓17幢(苏州市吴中区)\",\"name\":\"胡\",\"phone\":\"18143314474\",\"userId\":252}}";
        LogisticsCommonData logisticsCommonData =  LogisticsGoodsUtil.parseObject(lgContent);
        body.initLogisticsData(logisticsCommonData);
        ShunfengResponseData<ShunfengResposeCreateOrder> orderRst = ThirdLogisticShunFengTool.createOrder(body);
        System.out.println(JacksonUtil.gson.toJson(orderRst));

        String trackingNumber = "SF1040407960064";
        String checkPhoneNo = "4474";
        ShunfengResponseData<ShunfengRespRouteData> routeData = ThirdLogisticShunFengTool.getRouteData(trackingNumber, checkPhoneNo);
        System.out.println(JacksonUtil.gson.toJson(routeData));
    }

}
